﻿// Decompiled with JetBrains decompiler
// Type: Netick.LossCalculator
// Assembly: Netick, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 6726ECA1-C773-4CF7-8952-E81B30D93B52
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.xml

using System.Runtime.CompilerServices;

#nullable disable
namespace Netick;

internal struct LossCalculator(float expectedPacketsPerWindow, float burstTicksWindow)
{
  public float LossRate = 0.0f;
  public int LossBurst = 0;
  private int _curBurst = 0;
  private int _lostPackets = 0;
  private Tick _basis = Tick.InvalidTick;
  private Tick _lastTick = Tick.InvalidTick;
  private Tick _burstTick = Tick.InvalidTick;
  private readonly int _burstTicksWindow = (int) burstTicksWindow;
  private readonly int _expectedPacketsPerWindow = (int) expectedPacketsPerWindow;

  [MethodImpl(MethodImplOptions.AggressiveInlining)]
  public void OnTickReceive(Tick receiveTick)
  {
    if (!this._basis.IsValid)
    {
      this._lastTick = receiveTick;
      this._basis = receiveTick;
      this._burstTick = receiveTick;
    }
    else
    {
      int num1 = receiveTick - this._lastTick;
      int num2 = receiveTick - this._basis;
      int num3 = num1 - 1;
      int num4 = receiveTick - this._burstTick;
      if (num3 > this._curBurst)
      {
        int num5 = num3 > 1 ? num3 : 0;
        if (num5 > this._curBurst)
        {
          if (this.LossBurst == 0)
            this.LossBurst = num5;
          this._curBurst = num5;
        }
      }
      int burstTicksWindow = this._burstTicksWindow;
      if (num4 >= burstTicksWindow)
      {
        this.LossBurst = this._curBurst;
        this._curBurst = 0;
        this._burstTick = receiveTick;
      }
      if (num2 >= this._expectedPacketsPerWindow)
      {
        int num6 = num2 - this._expectedPacketsPerWindow;
        this._lostPackets += num3 - num6;
        this.LossRate = (float) this._lostPackets / (float) this._expectedPacketsPerWindow;
        this._lostPackets = num6;
        this._basis = receiveTick;
      }
      else
        this._lostPackets += num3;
      this._lastTick = receiveTick;
    }
  }

  public void Reset()
  {
    this._lostPackets = 0;
    this._basis = Tick.InvalidTick;
    this._lastTick = Tick.InvalidTick;
    this._burstTick = Tick.InvalidTick;
    this.LossBurst = 0;
    this.LossRate = 0.0f;
    this._curBurst = 0;
  }
}
